package com.itchu.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itchu.common.domain.PageResult;
import com.itchu.common.exption.ExceptionEnum;
import com.itchu.common.exption.MusicException;
import com.itchu.common.utils.SendMsgUtils;
import com.itchu.system.domain.Singer;
import com.itchu.system.domain.Song;
import com.itchu.system.domain.User;
import com.itchu.system.mapper.SingerMapper;
import com.itchu.system.mapper.SongMapper;
import com.itchu.system.mapper.UserMapper;
import com.itchu.system.service.UserService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SendMsgUtils sendMsgUtils;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private SongMapper songMapper;

    @Autowired
    private SingerMapper singerMapper;
    /**
     * 查找用户的分页信息
     * @param key   搜索条件
     * @param page  当前页
     * @param rows  页大小
     * @param sortBy
     * @param desc
     * @return
     */
    @Override
    public PageResult<User> findByPage(String key, Integer page, Integer rows, String sortBy, Boolean desc) {
        //开启分页
        PageHelper.startPage(page,rows);
        //创建一个封装条件的对象
        Example example = new Example(User.class);
        if (!StringUtils.isEmpty(key)) {
            Example.Criteria criteria = example.createCriteria();
            criteria.orLike("name","%" + key + "%");
            criteria.orLike("id","%" + key + "%");
        }
        if (!StringUtils.isEmpty(sortBy)) {
            example.setOrderByClause(sortBy+" "+(desc ? "desc" : "asc"));
        }
        List<User> users = userMapper.selectByExample(example);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        return new PageResult<>(pageInfo.getTotal(),pageInfo.getPages(),users);
    }

    /**
     * 修改用户信息
     * @param user
     * @return
     */
    @Override
    public User updateUser(User user) {
        if (user != null) {
            //密码采用加盐加密
//            String oldPassword = user.getPassword();
//            String newPassword = passwordEncoder.encode(oldPassword);
//            user.setPassword(newPassword);

            user.setUpdateTime(new Date());
            int i = userMapper.updateByPrimaryKeySelective(user);
            if (i != 1) {
                throw new MusicException(ExceptionEnum.MUSIC_FAIL_USER);
            }

            User u = userMapper.selectByPrimaryKey(user.getId());
            return u;
        }
        return null;
    }

    /**
     * 检查用户名或者电话是否已被注册
     * @param type  1是用户名， 2是手机
     * @param value  用户名或者手机号
     * @return
     */
    @Override
    public Boolean checkNameAndPhone(Long type, String value) {
        User user = new User();
        if (type.equals(1L)) {
            user.setUsername(value);
        }else if (type.equals(2L)) {
            user.setPhone(value);
        }
        // 有此用户则返回false,无则true
        User user1 = userMapper.selectOne(user);
        if (user1 == null) {
            return true;
        }else {
            return false;
        }
    }

    /**
     * 向阿里云发送验证码操作
     * @return
     */
    @Override
    public void sendCode(String phone) {
        // 1.生成6位随机数
        String code = RandomStringUtils.randomNumeric(6);
        // 2.存进redis里面,key为电话，value是验证码
        // 第一个参数是PHONE:CODE:电话号 因为以后可能需要手机号做其他业务，key如果直接是手机号就会被覆盖
        // 第二个参数是验证码，后面两个是过期时间，3是10，4单位是分钟
        redisTemplate.opsForValue().set("PHONE:CODE:"+phone,code,10, TimeUnit.DAYS);

        // 3.发送短信
        sendMsgUtils.sendCheckCodeMsg(phone,code);
    }

    /**
     * 注册业务
     * @param user  用户的信息
     * @param code  验证码
     * @return
     */
    @Override
    public Boolean register(User user, String code) {

        // 1.判断验证码是否正确
        String rediscode = redisTemplate.opsForValue().get("PHONE:CODE:" + user.getPhone());

        if (!rediscode.equals(code)) {
            throw new MusicException(ExceptionEnum.MUSIC_INVALID_CHECKCODE);
        }

        // 2.密码动态加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        user.setMySignature("这个人很懒，什么没有个性签名");
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setState(1);
        int i = userMapper.insertSelective(user);
        return i == 1;
    }

    /**
     * 登录操作
     * @param username
     * @param password
     * @return
     */
    @Override
    public User login(String username, String password) {
        // 1.根据用户名查找用户
        User record = new User();
        record.setUsername(username);
        User user = userMapper.selectOne(record);

        if (user == null) {
            return null;
        }

        // 2.加密用户密码，然后比对
        boolean matches = passwordEncoder.matches(password, user.getPassword());

        // 3. 如果不正确抛出异常
        if (!matches) {
            throw new MusicException(ExceptionEnum.MUSIC_INVALID_USERNAME_PASSWORD_ERROR);
        }
        return user;
    }

    /**
     * 用户上传歌曲的操作
     * @param song
     * @param userId
     * @param cids
     * @return
     */
    @Override
    public void uploadSong(Song song, Long userId, List<Long> cids) {
        if (song == null) {
            throw new RuntimeException("歌曲为空");
        }
        if (userId == null) {
            throw new RuntimeException("用户id为空");
        }
        if (CollectionUtils.isEmpty(cids)) {
            throw new RuntimeException("风格为空");
        }
        //1.保存歌曲信息
        song.setCount(0);
        song.setState(1);    // 状态为0是通过，1是待审核，2是审核不通过
        song.setCreateTime(new Date());
        song.setUpdateTime(new Date());
        songMapper.insert(song);
        Long sid = song.getId();
        //2.向歌曲-分类表这个中间表添加记录
        songMapper.delSongIdAndCategoryIdBySid(sid);
        songMapper.addSongIdAndCategoryId(sid,cids);

        //3. 向用户_上传表中添加一条上传记录
        userMapper.addUploadRecord(userId,song.getId());
    }

    @Override
    public List<Song> getUploadSongByUId(Long userId) {
        List<Song> list = userMapper.getUploadSongByUId(userId);
        List<Singer> singers = singerMapper.selectAll();
        list.stream().forEach(song -> {
            singers.stream().forEach(singer -> {
                if (song.getSingerId().equals(singer.getId())) {
                    song.setSinger(singer);
                }
            });
        });
        return list;
    }


    /**
     * 删除用户信息
     * @param id
     * @return
     */
    @Override
    public void deletUser(Long id) {
        userMapper.deleteByPrimaryKey(id);
    }
}